package abacab.actor;

import abacab.message.Envelope;

/**
 * A base implementation of an actor
 * 
 * @param <M>
 *          the type of handled message
 */
public abstract class Actor<M> {
	/** The actor context */
	private ActorContext	actorContext;

	/**
	 * Initialization method launched just after the context has been set
	 */
	public void init() {
		// Nothing to do
	}

	/**
	 * @param actorContext
	 *          the actor's context
	 */
	public final void setActorContext(ActorContext actorContext) {
		if (this.actorContext != null) {
			throw new IllegalAccessError("It is not allowed to set the actor's context once the actor is created");
		}
		this.actorContext = actorContext;
	}

	/**
	 * @return the actor's context
	 */
	public final ActorContext getActorContext() {
		return this.actorContext;
	}

	/**
	 * Indicates if the actor is ready for execution.<br />
	 * An implementation can decide that an actor is not executable for some reason and its execution will be postponed until it becomes available.
	 * 
	 * @return true if the actor is ready for execution
	 */
	public boolean isReadyForExecution() {
		return true;
	}

	/**
	 * Indicates that the actor has finished handling a message
	 */
	public void afterExecution() {
		// nothing to do
	}

	/**
	 * Process a message
	 * 
	 * @param message
	 *          the message
	 */
	public abstract void onMessage(Envelope<M> message);
}